package com.exam.practice;

import java.util.Scanner;
import java.util.Stack;

/**
 * @Author: xin.wang  E-mail:xin.wang1@myt11.com
 * @CreateTime: 2022/1/20 11:32
 * @Description: 表达式求值
 */
public class SeventhPractice {
    /**
     * 请写一个整数计算器，支持加减乘三种运算和括号。
     * <p>
     * 示例1
     * 输入："1+2"  返回值：3
     * 示例2
     * 输入："(2*(3-4))*5"  返回值：-10
     * 示例3
     * 输入："3+2*3*4-1"  返回值：26
     *
     * @param args
     */
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("输入:");

        String space = input.nextLine();
        String[] separated = space.split("\\b");//数字和运算符隔开

        Stack<Integer> numbers = new Stack<>(); //数字栈
        Stack<String> operator = new Stack<>(); //运算符栈

        for (String str : separated) {
            if (isOperator(str)) {
                int nowPriority = priority(str);//记录当前优先级
                while (true) {
                    int topPriority = 0;
                    //有无运算符
                    if (operator.isEmpty() == false) {
                        String top = operator.peek();
                        topPriority = priority(top);
                    } else {
                        operator.push(str);
                        break;
                    }

                    if (nowPriority > topPriority) {
                        operator.push(str);
                        break;
                    } else {
                        String o = "0";
                        int num1 = 0;
                        int num2 = 0;
                        if (operator.isEmpty() == false) {
                            o = operator.pop();
                        }
                        if (numbers.isEmpty() == false) {
                            num1 = numbers.pop();
                            num2 = numbers.pop();
                        }
                        numbers.push(operation(o, num1, num2));
                    }
                }
            } else {
                int number = Integer.valueOf(str);
                numbers.push(number);
            }
        }

        //运算符栈是否为空
        while (true) {
            if (operator.isEmpty() == false) {
                String o = "0";
                o = operator.pop();
                int num1 = 0;
                int num2 = 0;
                if (numbers.isEmpty() == false) {
                    num1 = numbers.pop();
                    num2 = numbers.pop();
                }
                numbers.push(operation(o, num1, num2));
            } else {
                break;
            }
        }

        System.out.print("返回值:" + numbers.pop());
        input.close();
    }

    /**
     * 运算
     *
     * @param o
     * @param num1
     * @param num2
     * @return
     */
    public static int operation(String o, int num1, int num2) {
        int sum = 0;
        switch (o) {
            case "+": {
                sum = num1 + num2;
                break;
            }
            case "-": {
                sum = num2 - num1;
                break;
            }
            case "*": {
                sum = num1 * num2;
                break;
            }
        }
        return sum;
    }

    /**
     * 运算符判断
     *
     * @param operator
     * @return
     */
    public static boolean isOperator(String operator) {
        if (operator.equals("+") || operator.equals("-") || operator.equals("*") ) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 优先级判断
     *
     * @param o
     * @return
     */
    public static int priority(String o) {
        int pri = 0;
        switch (o) {
            case "+": {
                pri = 0;
                break;
            }
            case "-": {
                pri = 0;
                break;
            }
            case "*": {
                pri = 1;
                break;
            }
        }
        return pri;
    }

//    public boolean priority(String a, String b){
//        int oneNum = priority(a);
//        int twoNum = priority(b);
//        if (oneNum > twoNum) {
//            return true;
//        }else {
//            return false;
//        }
//    }
}
